package com.beiding.fastmock.fram;

import cn.hutool.core.io.watch.WatchMonitor;
import cn.hutool.core.io.watch.Watcher;
import cn.hutool.core.lang.Console;
import com.sun.nio.file.SensitivityWatchEventModifier;

import java.io.File;
import java.io.IOException;
import java.nio.file.*;

import static org.eclipse.collections.impl.block.factory.StringPredicates.endsWith;

/**
 * 检查文件变更
 *
 * @author 丁常磊
 * @date 2021/7/14 13:55
 */

public class FileChecker extends Thread {

    private boolean closed = false;


    private ChangeCallback changeCallback;
    private WatchMonitor watchMonitor;

    private File targetFile;

    public FileChecker(File targetFile) {
        this.targetFile = targetFile;
    }

    public void close() {
        this.closed = true;
        watchMonitor.close();
    }

    @Override
    public void run() {

        if (closed) {
            throw new RuntimeException("已被关闭");
        }

        if (targetFile == null) {
            throw new RuntimeException("目标文件不存在");
        }

        watchMonitor = WatchMonitor.create(targetFile, WatchMonitor.EVENTS_ALL);

        watchMonitor.setWatcher(new Watcher() {

            @Override
            public void onCreate(WatchEvent<?> event, Path currentPath) {
                onChange(event.context());
            }

            @Override
            public void onModify(WatchEvent<?> event, Path currentPath) {
                onChange(event.context());
            }

            @Override
            public void onDelete(WatchEvent<?> event, Path currentPath) {
                onChange(event.context());
            }

            @Override
            public void onOverflow(WatchEvent<?> event, Path currentPath) {
                onChange(event.context());
            }
        });

        //设置监听目录的最大深入，目录层级大于制定层级的变更将不被监听，默认只监听当前层级目录
        watchMonitor.setMaxDepth(20);
        //启动监听
        watchMonitor.start();

    }

    interface ChangeCallback {
        /**
         * 改变后的回调
         */
        void onChange();
    }


    private void onChange(Object ctx) {
        //只观察js文件变化
        if (ctx.toString().endsWith(".js")) {
            TaskCenter.task(() -> {
                if (changeCallback != null) {
                    try {
                        changeCallback.onChange();
                    } catch (Exception ignore) {
                    }
                }
            });
        }
    }

    public void setChangeCallback(ChangeCallback changeCallback) {
        this.changeCallback = changeCallback;
    }

}
